package com.tengju.bff.interfaces.covercharge.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tengju.bff.interfaces.covercharge.constant.*;
import com.tengju.bff.interfaces.covercharge.entity.bo.SignContractPersonBo;
import com.tengju.bff.interfaces.covercharge.entity.po.*;
import com.tengju.bff.interfaces.covercharge.entity.vo.LeTaxRegisteredAndReturnResult;
import com.tengju.bff.interfaces.covercharge.entity.vo.contract.*;
import com.tengju.bff.interfaces.covercharge.handler.CoverChargeException;
import com.tengju.bff.interfaces.covercharge.mapper.ServiceContractCertificateMapper;
import com.tengju.bff.interfaces.covercharge.mapper.ServiceContractMapper;
import com.tengju.bff.interfaces.covercharge.mapper.ServiceContractRelationMapper;
import com.tengju.bff.interfaces.covercharge.mapper.ServiceSelfCertificationMapper;
import com.tengju.bff.interfaces.covercharge.service.*;
import com.tengju.bff.interfaces.covercharge.service.bestsign.BestSignClient;
import com.tengju.bff.interfaces.covercharge.service.bestsign.constant.BestSignConstant;
import com.tengju.bff.interfaces.covercharge.service.bestsign.impl.contract.BestSignApplyCertService;
import com.tengju.bff.interfaces.covercharge.service.bestsign.impl.contract.BestSignContractService;
import com.tengju.bff.interfaces.covercharge.util.DateTimeUtils;
import com.tengju.bff.interfaces.covercharge.util.alarmUtil.MsgSendUtil;
import com.tengju.bff.interfaces.shared.ApiResponse;
import com.zoi7.component.core.exception.ServiceException;
import com.zoi7.component.core.util.MD5Utils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.text.MessageFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author liang_shi
 * @date 2020/7/14 10:47
 * @description 合同服务实现
 */
@Slf4j
@Service
public class ServiceContractServiceImpl extends ServiceImpl<ServiceContractMapper, ServiceContract> implements IServiceContractService {

    @Autowired
    private BestSignApplyCertService bestSignApplyCertService;

    @Autowired
    private BestSignContractService bestSignContractService;

    @Autowired
    private ServiceContractCertificateMapper contractCertificateMapper;

    @Autowired
    private ServiceContractRelationMapper contractRelationMapper;

    @Autowired
    private ServiceContractMapper contractMapper;

    @Autowired
    private IServiceRabbitMqService rabbitMqService;

    @Autowired
    private ServiceSelfCertificationMapper serviceSelfCertificationMapper;

    @Autowired
    private MemberAddStartServiceImpl memberService;

    @Autowired
    private IServiceLetaxRegisteredService letaxRegisteredService;

    @Autowired
    @Lazy
    private IServiceSignService serviceSignService;

    @Autowired
    private IServiceContractTemplateService contractTemplateService;

    @Autowired
    private IServiceSignRecordService serviceSignRecordService;

    @Autowired
    private BestSignClient bestSignClient;

    /**
     * 重试次数
     */
    private static final int RETRY_NUM = 10;

    /**
     * 签约失败描述
     */
    private static final String RETURN_MSG = "抱歉，由于\"{0}\",签约失败，请尽快重新签约。";

    /**
     * 认证结束后调用该方法申请用户证书
     *
     * @param idCode 会员Id
     * @param reqVo  请求
     */
    @Override
    public void applyCertificate(String platformCode, Integer idCode, Integer userFrom, ApplyCertificateReqVo reqVo) {
        String transId = String.valueOf(IdWorker.getId());
        log.info("注册并申请证书开始,idCode:{},业务流水号:{},请求:{}", idCode, transId, reqVo);
        ServiceContractCertificate scc = createContractCert(transId, platformCode, idCode, userFrom, reqVo);
        int num = contractCertificateMapper.insert(scc);
        if (num == 1) {
            ApplyCertificateResVo resVo = bestSignApplyCertService.applyCert(transId, reqVo);
            ServiceContractCertificate updateScc = new ServiceContractCertificate();
            updateScc.setId(scc.getId());
            updateScc.setTaskId(resVo.getTaskId());
            contractCertificateMapper.updateById(updateScc);
            //消息发送队列
            //sendCertApplyMessage(transId, idCode, reqVo, resVo);
        } else {
            log.error("注册并申请证书入库异常,需要重试或者人工处理，idCode:{},流水号：{}", idCode, transId);
            MsgSendUtil.sendLarkMsg("注册并申请证书入库异常,需要重试或者人工处理,idCode:{},流水号：{}，异常：{}", idCode, transId);
            throw new ServiceException("系统异常");
        }
        log.info("注册并申请证书结束");
    }

    /**
     * 通知申请证书结果
     *
     * @param resultBizMap 通知结果
     */
    @Override
    public void notifyCertApply(HashMap resultBizMap) {
        String params = String.valueOf(resultBizMap.get("params"));
        HashMap paramMap = JSON.parseObject(params, HashMap.class);
        String message = String.valueOf(paramMap.get("message"));
        String account = String.valueOf(paramMap.get("account"));
        String taskId = String.valueOf(paramMap.get("taskId"));
        String code = String.valueOf(paramMap.get("code"));
        String status = String.valueOf(paramMap.get("status"));
        log.info("通知申请证书结果,status:{},account:{},taskId:{}", status, account, taskId);
        ServiceContractCertificate queryScc = new ServiceContractCertificate();
        queryScc.setAccount(account);
        queryScc.setTaskId(taskId);
        ServiceContractCertificate sccInfo = contractCertificateMapper.selectOne(new QueryWrapper<>(queryScc));
        if(Objects.isNull(sccInfo)){
            //循环查
            int i = 0;
            while (i < 3) {
                sccInfo = contractCertificateMapper.selectOne(new QueryWrapper<>(queryScc));
                if(Objects.nonNull(sccInfo)){
                    break;
                }
                try
                {
                    //此处休眠1000毫秒，因为插入数据库事务可能没有提交完毕，此时第三方回调过来通知
                    Thread.sleep(1000);
                }catch(Exception e){
                    log.error("通知申请证书结果处理[睡眠时间有错],account:{},taskId:{}", account, taskId);
                }
                i++;
            }
        }

        if(Objects.isNull(sccInfo)){
            log.error("通知申请证书结果处理[本地数据不存在],account:{},taskId:{}", account, taskId);
            return;
        }

        if (!CertStatusEnum.PROCESSING.getStatus().equals(sccInfo.getStatus())) {
            log.info("通知申请证书结果处理[数据已更新],account:{},taskId:{}", account, taskId);
            return;
        }
        String certStatus;
        String certId = null;
        switch (status) {
            case "-1":
            case "0":
            case "3":
            case "6":
                //超时-失败重试
                certStatus = CertStatusEnum.FAILED.getStatus();
                break;
            case "1":
            case "2":
                //申请中-不处理
                return;
            case "4":
                //看错误信息处理
                certStatus = CertStatusEnum.FAILED.getStatus();
                break;
            case "5":
                certStatus = CertStatusEnum.SUCCESS.getStatus();
                //获取证书编号
                try {
                    certId = bestSignApplyCertService.queryApplyCertId(sccInfo.getBizId(),
                            sccInfo.getAccount());
                } catch (Exception e) {
                    log.warn("流水号：{},获取证书编号失败", sccInfo.getBizId());
                }
                break;
            default:
                certStatus = CertStatusEnum.UNKNOWN.getStatus();
                break;
        }
        ServiceContractCertificate updateInfo = new ServiceContractCertificate();
        updateInfo.setId(sccInfo.getId());
        updateInfo.setStatus(certStatus);
        updateInfo.setErrorCode(code);
        updateInfo.setMessage(message);
        updateInfo.setCertId(certId);
        updateInfo.setUpdateTime(DateTimeUtils.now());
        contractCertificateMapper.updateById(updateInfo);
    }

    /**
     * 处理证书状态同步
     *
     * @param deliveryTag tag
     * @param channel     mqChannel
     * @param message     消费消息
     */
//    @Override
//    public void dealMqCertApplyMessage(Long deliveryTag, Channel channel, RabbitMqMessage message) {
//        try {
//            //获取消息体
//            ApplyCertificateMqVo mqVo = JSON.parseObject(JSON.toJSONString(message.getMessageBody()), ApplyCertificateMqVo.class);
//            log.info("流水号：{},处理证书申请状态开始", message.getMessageId());
//            ServiceContractCertificate queryScc = new ServiceContractCertificate();
//            queryScc.setBizId(mqVo.getTransId());
//            ServiceContractCertificate sccInfo = contractCertificateMapper.selectOne(new QueryWrapper<>(queryScc));
//            if (Objects.isNull(sccInfo)) {
//                log.warn("申请证书信息不存在,account:{},taskId:{}", mqVo.getAccount(), mqVo.getTransId());
//                channel.basicAck(deliveryTag, true);
//                return;
//            }
//            if (!CertStatusEnum.PROCESSING.getStatus().equals(sccInfo.getStatus())) {
//                log.info("申请证书信息处理[数据已更新],mqVo:{}", mqVo);
//                channel.basicAck(deliveryTag, true);
//                return;
//            }
//
//            ServiceContractCertificate updateInfo = new ServiceContractCertificate();
//            String status;
//            String errorCode;
//            String errorMsg;
//            String certId = null;
//            try {
//                ApplyCertificateStatusResVo resVo = bestSignApplyCertService.queryApplyCertStatus(mqVo.getTransId(),
//                        mqVo.getAccount(), mqVo.getTaskId());
//                //1：新申请 2：申请中 3：超时 4：申请失败 5：成功 6：失败重试 -1：无效的申请（系统异常） 0：taskId不存在或已过期
//                errorCode = resVo.getStatus();
//                errorMsg = resVo.getMessage();
//                switch (resVo.getStatus()) {
//                    case "-1":
//                    case "0":
//                    case "3":
//                    case "6":
//                        //超时-失败重试
//                        status = CertStatusEnum.FAILED.getStatus();
//                        channel.basicAck(deliveryTag, true);
//                        log.error("证书申请状态-申请失败，需要处理,status:{}", resVo.getStatus());
//                        MsgSendUtil.sendDingMsg("流水号：{},证书申请状态-申请失败，需要处理,status:{}", message.getMessageId(), resVo.getStatus());
//                        break;
//                    case "1":
//                    case "2":
//                        //重试消费
//                        rabbitMqService.retrySendMessage(RETRY_NUM, deliveryTag, channel, message, CertApplyDelayTimeUtil.getDelay(message.getNum() + 1));
//                        return;
//                    case "4":
//                        //看错误信息处理
//                        status = CertStatusEnum.FAILED.getStatus();
//                        channel.basicAck(deliveryTag, true);
//                        log.warn("证书申请状态-申请失败，需要处理,status:{}", resVo.getStatus());
//                        break;
//                    case "5":
//                        status = CertStatusEnum.SUCCESS.getStatus();
//                        //获取证书编号
//                        try {
//                            certId = bestSignApplyCertService.queryApplyCertId(mqVo.getTransId(),
//                                    mqVo.getAccount());
//                        } catch (Exception e) {
//                            log.warn("流水号：{},获取证书编号失败", message.getMessageId());
//                        }
//                        //取消消费
//                        channel.basicAck(deliveryTag, true);
//                        break;
//                    default:
//                        status = CertStatusEnum.UNKNOWN.getStatus();
//                        break;
//
//                }
//            } catch (CoverChargeException ce) {
//                status = CertStatusEnum.FAILED.getStatus();
//                errorCode = ce.getCode();
//                errorMsg = ce.getMsg();
//                channel.basicAck(deliveryTag, true);
//            }
//            updateInfo.setStatus(status);
//            updateInfo.setErrorCode(errorCode);
//            updateInfo.setMessage(errorMsg);
//            updateInfo.setCertId(certId);
//            ServiceContractCertificate updateScc = new ServiceContractCertificate();
//            updateScc.setBizId(mqVo.getTransId());
//            updateInfo.setUpdateTime(DateTimeUtils.now());
//            contractCertificateMapper.update(updateInfo, new UpdateWrapper<>(updateScc));
//        } catch (Exception e) {
//            log.error("流水号：{},处理证书申请状态异常:{}", message.getMessageId(), Throwables.getStackTraceAsString(e));
//            MsgSendUtil.sendDingMsg("流水号：{},处理证书申请状态异常", message.getMessageId());
//        }
//        //重试消费
//        rabbitMqService.retrySendMessage(RETRY_NUM, deliveryTag, channel, message, CertApplyDelayTimeUtil.getDelay(message.getNum() + 1));
//    }

    /**
     * @param transId 业务流水
     * @param idCode  会员idcode
     * @param reqVo   请求
     * @return 结果
     */
    private ServiceContractCertificate createContractCert(String transId, String platformCode, Integer idCode,
                                                          Integer userFrom, ApplyCertificateReqVo reqVo) {
        ServiceContractCertificate scc = new ServiceContractCertificate()
                .setIdCode(idCode).setPlatformCode(platformCode).setBizId(String.valueOf(transId))
                .setAccount(reqVo.getAccount()).setUserType(reqVo.getUserType().getType())
                .setUserFrom(userFrom);
        //个人
        if (ContractUserTypeEnum.SINGLE.getType().equals(reqVo.getUserType().getType())) {
            PersonCertApplyVo person = reqVo.getPerson();
            scc.setName(person.getName());
            scc.setMarkNo(person.getIdentity());
            scc.setIdentityType(person.getIdentityType().getType());
        } else {
            CompanyCertApplyVo company = reqVo.getCompany();
            scc.setName(company.getName());
            scc.setMarkNo(company.getRegCode());
        }
        scc.setStatus(CertStatusEnum.PROCESSING.getStatus());
        scc.setCreateTime(DateTimeUtils.now());
        scc.setUpdateTime(DateTimeUtils.now());
        return scc;
    }


    /**
     * 发送用户证书申请信息
     *
     * @param resVo 请求信息
     */
//    public void sendCertApplyMessage(String transId, Integer idCode, ApplyCertificateReqVo reqVo, ApplyCertificateResVo resVo) {
//        String topic = MqMessageConstants.SERVICE_CERT_APPLY_NOTIFY;
//        String routeKey = MqMessageConstants.SERVICE_CERT_APPLY_CALLBACK;
//        RabbitMqMessage mqMessage = new RabbitMqMessage();
//        mqMessage.setMessageId(transId);
//        mqMessage.setTopic(topic);
//        mqMessage.setRouteKey(routeKey);
//        mqMessage.setNum(1);
//        ApplyCertificateMqVo mqVo = new ApplyCertificateMqVo();
//        mqVo.setIdCode(idCode);
//        mqVo.setAccount(reqVo.getAccount());
//        mqVo.setTransId(transId);
//        mqVo.setTaskId(resVo.getTaskId());
//        mqMessage.setMessageBody(mqVo);
//        mqMessage.setCreateTime(new Date());
//        //1分钟后消费
//        rabbitMqService.sendMessage(topic, routeKey, mqMessage, CertApplyDelayTimeUtil.getDelay(1));
//    }

    /**
     * 签署合同
     * <p>
     * 暂不支持三方以上用户签署
     *
     * @param platformCode 平台
     * @param idCode       会员
     * @param reqVo        请求
     * @return 手动签署地址
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ApiResponse<SignContractResVo> signContract(String platformCode, Integer idCode, SignContractReqVo reqVo) {
        SignContractResVo result = new SignContractResVo();
        String transId = String.valueOf(IdWorker.getId());
        try {
            log.info("签署合同处理开始,platformCode:{},idCode:{},流水号:{}", platformCode, idCode, transId);
            //判断是否有资质-会员
//            if (!checkIsZzShSuc(idCode)) {
//                return ApiResponse.newFailure(CoverChargeErrorCode.BUSINESS_ERROR.getCode(), "资质审核未通过，不能签署");
//            }

            //查询w_service_self_certification表用户信息
            //SignContractPersonBo scp = querySscInfo(platformCode, idCode, reqVo);

            //查询签约信息
            Integer type=queryIdentityType(platformCode, idCode);
            reqVo.setType(type);
            //查询身份对应信息
            SignContractPersonBo scp = queryIdentityInfo(type,platformCode, idCode);

            if (!checkIsAuthSuc(reqVo.getType(), scp)) {
                return ApiResponse.newFailure(CoverChargeErrorCode.BUSINESS_ERROR.getCode(), "签署合同失败,认证未成功");
            }
            //判断用户证书是否申请完成
            if (!checkCert(platformCode, idCode, reqVo, scp.getSignIdCardNo(), scp.getCompanyNo(), Boolean.TRUE)) {
                return ApiResponse.newFailure(CoverChargeErrorCode.BUSINESS_ERROR.getCode(), "签署合同失败：证书申请失败");
            }
            //签署方(个人账户+企业账户)
            String account = MD5Utils.MD5Encode(scp.getSignIdCardNo()) + "," + MD5Utils.MD5Encode(scp.getCompanyNo());
            //判断是否有在签署
//            if (checkIsSign(platformCode, idCode, reqVo.getType(), account)) {
//                return ApiResponse.newFailure(CoverChargeErrorCode.BUSINESS_ERROR.getCode(), "签署已完成，无需重复签署");
//            }
            SignContractTemplateReqVo templateReqVo = new SignContractTemplateReqVo();
            templateReqVo.setContractType(reqVo.getContractType());
            SignContractTemplateResVo resVo = contractTemplateService.queryContractTemplate(templateReqVo);
            Assert.isTrue(!Objects.isNull(resVo), "获取合同模板为空");
            //获取模板Id
            String templateNo = resVo.getTemplateNo();
            //获取模板变量
            List<TemplateVarsVo> tvvList = bestSignContractService.getContractTemplateVars(transId, templateNo);

            //创建合同
            ContractCreateReq createReq = createContractByTemplate(templateNo, tvvList, scp, reqVo.getType());
            String contractId = bestSignContractService.createContract(transId, createReq);
            log.info("创建合同结束,contractId:{}", contractId);
            //入库
            ServiceContractRelation relation = createContractRelation(transId, scp, resVo.getId(), contractId, account);
            int relationNum = contractRelationMapper.insert(relation);
            Assert.isTrue(relationNum == 1, "创建合同关系异常");
            int contractNum = contractMapper.insert(createContract(templateNo, contractId));
            Assert.isTrue(contractNum == 1, "创建合同异常");
            //生成公司企业印章图片
            //bestSignContractService.createCompanySignatureImage(transId, getCreateDcCompanySignatureReq());
            //生成公司企业印章图片
            bestSignContractService.contractUpdateImage(transId, getCreateDcCompanySignatureReq(bestSignClient.getAccount()));
            //生成用户签名/印章图片
            bestSignContractService.createUserSignatureImage(transId, getCreateUserSignatureReq(scp));
            //生成企业印章图片
            bestSignContractService.createCompanySignatureImage(transId, getCreateCompanySignatureReq(scp));
            //甲乙方自动签
            bestSignContractService.signContractByAuto(transId, getAutoSignReq(templateNo, contractId, scp.getCompanyNo(), tvvList,bestSignClient.getAccount()));
            //乙方手动签
            HandSignContractRes hsr = bestSignContractService.signContractByHand(transId, getHandSignReq(transId,
                    templateNo, contractId, tvvList, scp, reqVo));
            log.info("获取用户手动签地址结束，contractId:{}", contractId);
            //更新库操作
            int updateRelationNum = contractRelationMapper.updateById(updateContractRelation(relation.getId(), hsr.getShortUrl(), createReq.getExpireTime()));
            Assert.isTrue(updateRelationNum == 1, "更新合同关系异常");
            //结果
            result.setSignUrl(hsr.getShortUrl());
            result.setContractId(contractId);
        } catch (ServiceException e) {
            log.error("idCode:{},流水号:{},签署合同异常:", idCode, transId, e);
            return ApiResponse.newFailure(CoverChargeErrorCode.BUSINESS_EXCEPTION.getCode(), e.getMessage());
        } catch (Exception e) {
            log.error("idCode:{},流水号:{},签署合同异常:", idCode, transId, e);
            return ApiResponse.newFailure(CoverChargeErrorCode.SYS_ERROR.getCode(), "签署合同失败");
        }
        log.info("签署合同处理结束:{}", result);
        return ApiResponse.newSuccess(result);
    }


//    /**
//     * 查询会员用户资质审核结果
//     *
//     * @param idCode id_code
//     * @return 资质审核结果
//     */
//    private boolean checkIsZzShSuc(Integer idCode) {
//        Integer userId = UserUtils.getUserId(idCode);
//        JsonResult<Boolean> authRes = areaServiceFeignClient.getUserSucAudit(Long.valueOf(userId));
//        log.info("查询会员用户资质审核结果：{}", authRes);
//        if (Objects.isNull(authRes) || Objects.isNull(authRes.getData())) {
//            return Boolean.FALSE;
//        }
//        return authRes.getData();
//    }


    /**
     * 检查是否签署
     *
     * @param platformCode 平台
     * @param idCode       用户idCode
     * @param userFrom     来源类型
     * @return 结果      * 签署中 返回true
     */
    private boolean checkIsSign(String platformCode, Integer idCode, Integer userFrom, String account) {
        log.info("检查是否签署,platformCode:{},idCode:{},type:{}", platformCode, idCode, userFrom);
        ServiceContractRelation relation = new ServiceContractRelation();
        relation.setIdCode(idCode);
        relation.setPlatformCode(platformCode);
        relation.setUserFrom(userFrom);
        List<ServiceContractRelation> scrList = contractRelationMapper.selectList(new QueryWrapper<>(relation)
                .orderByDesc("create_time"));
        if (!CollectionUtils.isEmpty(scrList)) {
            for (ServiceContractRelation scr : scrList) {
                if (!scr.getAccount().equals(account)) {
                    continue;
                }
                ServiceContract contract = new ServiceContract();
                contract.setContractId(scr.getContractId());
                ServiceContract sc = contractMapper.selectOne(new QueryWrapper<>(contract));
                if (Objects.isNull(sc)) {
                    continue;
                }
                if (ContractStatusEnum.SUCCESS.getStatus().equals(sc.getStatus())) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 签署合同通知结果
     *
     * @param resultBizMap 通知结果
     */
    @Override
    public void notifyContractSign(HashMap resultBizMap) {
        String params = String.valueOf(resultBizMap.get("params"));
        HashMap paramMap = JSON.parseObject(params, HashMap.class);
        String contractId = String.valueOf(paramMap.get("contractId"));
        String account = String.valueOf(paramMap.get("account"));
        //（2：已完成；3：已取消；）
        String signerStatus = String.valueOf(paramMap.get("signerStatus"));
        String errMsg = String.valueOf(paramMap.get("errMsg"));
        String code = String.valueOf(paramMap.get("code"));
        String sid = String.valueOf(paramMap.get("sid"));

        String bizId = String.valueOf(IdWorker.getId());
        log.info("通知签署合同结果处理,bizId:{},status:{},contractId:{}", bizId, signerStatus, contractId);
        ServiceContract querySc = new ServiceContract();
        querySc.setContractId(contractId);
        ServiceContract scInfo = contractMapper.selectOne(new QueryWrapper<>(querySc));
        if (Objects.isNull(scInfo)) {
            log.error("通知签署合同结果处理[本地数据不存在],account:{},contractId:{}", account, contractId);
            return;
        }
        if (ContractStatusEnum.SUCCESS.getStatus().equals(scInfo.getStatus())) {
            log.info("通知签署合同结果处理[数据已更新],account:{},contractId:{}", account, contractId);
            return;
        }
        ServiceContract updateSc = new ServiceContract();
        updateSc.setId(scInfo.getId());
        updateSc.setErrorCode(code);
        updateSc.setMessage(errMsg);
        updateSc.setUpdateTime(DateTimeUtils.now());
        boolean lock=Boolean.FALSE;
        if("2".equals(signerStatus)){
            //签署完成调用锁定合同
            lock = lockContract(contractId, bizId, updateSc);
        }else if("3".equals(signerStatus)){
            updateSc.setStatus(ContractStatusEnum.CANCEL.getStatus());
        }else{
            updateSc.setStatus(ContractStatusEnum.UNKNOWN.getStatus());
        }
        if (lock) {
            //补充合同信息
            fillContractInfo(contractId, bizId, updateSc);
        }
        contractMapper.updateById(updateSc);
        if(lock){
            //区域服务商签约成功用户入星接口
            memberService.dealMemberAddStart(bizId, contractId);
        }
    }

    @Override
    public ApiResponse<Boolean> lockSignContract(String platformCode, Integer idCode, String contractId) {
        String bizId = String.valueOf(IdWorker.getId());
        log.info("用户签署完成，锁定完成合同开始，入参platformCode:{},idCode:{},bizId:{},contractId:{}",
                platformCode, idCode, bizId, contractId);
        try {
            ServiceContract contract = new ServiceContract();
            contract.setContractId(contractId);
            ServiceContract sc = contractMapper.selectOne(new QueryWrapper<>(contract));
            if (Objects.isNull(sc)) {
                log.warn("查询合同信息结束，结果为空");
                return ApiResponse.newFailure(CoverChargeErrorCode.BUSINESS_ERROR.getCode(), "签署合同信息不存在,请重新签署");
            }
            if (ContractStatusEnum.SUCCESS.getStatus().equals(sc.getStatus())) {
                log.info("用户签署完成，签署合同结果[数据已更新]，锁定已完成");
                return ApiResponse.newSuccess(true);
            }

            ServiceContract updateSc = new ServiceContract();
            updateSc.setId(sc.getId());
            updateSc.setUpdateTime(DateTimeUtils.now());
            //签署完成调用锁定合同
            boolean lock = lockContract(contractId, bizId, updateSc);
            if(!lock){
                contractMapper.updateById(updateSc);
                return ApiResponse.newFailure(CoverChargeErrorCode.BUSINESS_ERROR.getCode(), "签署合同失败,请重新签署");
            }
            //补充合同信息
            fillContractInfo(contractId, bizId, updateSc);
            contractMapper.updateById(updateSc);
            //区域服务商签约成功用户入星接口
            memberService.dealMemberAddStart(bizId, contractId);
            return ApiResponse.newSuccess(true);
        } catch (Exception e) {
            log.error("锁定合同异常:", e);
            throw new ServiceException("签署合同失败,请重新签署");
        }
    }


    /**
     * 认证状态
     *
     * @param type     1-自认证企业 2-自认证个体工商户 3-乐税个体工商户
     * @param personBo 认证信息-状态
     * @return 结果
     */
    private boolean checkIsAuthSuc(Integer type, SignContractPersonBo personBo) {
        if (Objects.isNull(type)) {
            return false;
        }
        switch (type) {
            case 1:
            case 2:
                if (SelfCertificationStatus.PASS.getCode().equals(personBo.getStatus())) {
                    return true;
                }
                break;
            case 3:
                if (LetaxRegisteredStatusEnum.REGISTRATION_COMPLET.getCode().equals(personBo.getLeTaxStatus())
                        ||LetaxRegisteredStatusEnum.STAY_AUTH.getCode().equals(personBo.getLeTaxStatus())) {
                    return true;
                }
                break;
            default:
                break;

        }
        return false;
    }


    @Override
    public SignContractInfoResVo querySignContractInfo(String platformCode, Integer idCode,
                                                       SignContractInfoReqVo reqVo) {
        log.info("查询用户签署合同信息开始，入参,platformCode:{}，idCode:{}，reqVo:{}", platformCode, idCode, reqVo);
        ServiceContractRelation relation = new ServiceContractRelation();
        relation.setIdCode(idCode);
        relation.setPlatformCode(platformCode);
        relation.setUserFrom(reqVo.getType());
        //日切
//        String dayCut = ConfigUtil.getConfig().getString("sign.contract.day.cut",
//                DateTimeUtils.parseDateAsString(DateTimeUtils.getMonthFirstDay(new Date()), DateTimeUtils.DATE_FORMAT));
        ServiceContractRelation scrInfo = contractRelationMapper.selectOne(new QueryWrapper<>(relation)
                .orderByDesc("create_time").last("limit 1"));
        if (Objects.isNull(scrInfo)) {
            log.warn("查询用户签署合同信息结束，结果为空");
            return null;
        }
        SignContractInfoResVo infoResVo = new SignContractInfoResVo();
        infoResVo.setAccount(scrInfo.getAccount());
        infoResVo.setBizId(scrInfo.getBizId());
        infoResVo.setContractId(scrInfo.getContractId());

        String contractId = scrInfo.getContractId();
        ServiceContract contract = new ServiceContract();
        contract.setContractId(contractId);
        ServiceContract sc = contractMapper.selectOne(new QueryWrapper<>(contract));
        if (Objects.isNull(sc)) {
            log.warn("查询合同信息结束，结果为空");
            return null;
        }
        infoResVo.setId(sc.getId());

        ContractStatusEnum statusEnum = ContractStatusEnum.getInstance(sc.getStatus());
        if (Objects.isNull(statusEnum)) {
            statusEnum = ContractStatusEnum.UNKNOWN;
        }
        infoResVo.setStatus(statusEnum.getStatus());
        infoResVo.setStatusDesc(ContractStatusEnum.SUCCESS.getStatus().equals(sc.getStatus()) ?
                statusEnum.getMsg() : MessageFormat.format(RETURN_MSG, statusEnum.getMsg()));

        log.info("查询用户签署合同信息结束，infoResVo:{}", infoResVo);
        return infoResVo;
    }


    /**
     * 锁定合同
     *
     * @param contractId 合同Id
     * @param bizId      本地合同信息
     * @param updateSc   更新对象
     */
    private boolean lockContract(String contractId, String bizId, ServiceContract updateSc) {
        try {
            bestSignContractService.lockContract(bizId, contractId);
            updateSc.setStatus(ContractStatusEnum.SUCCESS.getStatus());
            return true;
        } catch (CoverChargeException se) {
            updateSc.setStatus(ContractStatusEnum.LOCK_FAILED.getStatus());
            updateSc.setErrorCode(se.getCode());
            updateSc.setMessage(se.getMsg());
        }
        return false;
    }

    /**
     * 填充合同信息
     *
     * @param contractId 合同Id
     * @param bizId      本地合同信息
     * @param updateSc   更新对象
     */
    private void fillContractInfo(String contractId, String bizId, ServiceContract updateSc) {
        try {
            ContractInfoRes contract = bestSignContractService.queryContractInfo(bizId, contractId);
            updateSc.setFileId(contract.getFid());
            Date sendTime = getStringTime(contract.getSendTime());
            updateSc.setSendTime(Objects.isNull(sendTime) ? DateTimeUtils.now() : sendTime);
            Date finishTime = getStringTime(contract.getFinishTime());
            updateSc.setFinishTime(Objects.isNull(finishTime) ? DateTimeUtils.now() : finishTime);
            updateSc.setSigners(contract.getSigners());
            updateSc.setDeveloperId(contract.getDeveloperId());
            updateSc.setUserId(contract.getUserId());

            //合同有效开始时间
            ServiceContract querySc = new ServiceContract();
            querySc.setStatus(ContractStatusEnum.SUCCESS.getStatus());
            ServiceContract oldScInfo = contractMapper.selectOne(new QueryWrapper<>(querySc)
                    .orderByDesc("finish_time").last("limit 1"));
            //1、如果为空，说明不是续签，取合同完成时间
            //2、判断上份合同过期时间跟当前完成时间比较，如果当前合同完成时间小于过期时间-3月或者大于过期时间，取合同完成时间
            if (Objects.isNull(oldScInfo) || updateSc.getFinishTime().compareTo(DateTimeUtils.addMonths(oldScInfo.getExpireDate(), -3)) < 0
                    || updateSc.getFinishTime().compareTo(oldScInfo.getExpireDate()) > 0) {
                updateSc.setBeginDate(updateSc.getFinishTime());
            } else {
                //否则取合同过期时间为有效开始时间
                updateSc.setBeginDate(oldScInfo.getExpireDate());
            }
            //合同到期时间-开始时间+1年
            Long expireTime = updateSc.getBeginDate().getTime() / 1000 + Long.valueOf(BestSignConstant.HOT_STORAGE_PERIOD);
            updateSc.setExpireDate(getSecondStringTime(String.valueOf(expireTime)));
        } catch (Exception e) {
            log.error("填充合同信息失败,contractId:{},异常信息:", contractId, e);
        }
    }

    /**
     * 校验证书是否完成
     *
     * @param platformCode 平台好
     * @param idCode       idcode
     * @param idCardNo     身份证号
     * @param companyNo    社会信用代码
     * @param isSuc        判断是否成功校验
     */
    @Override
    public boolean checkCert(String platformCode, Integer idCode, SignContractReqVo reqVo,
                             String idCardNo, String companyNo, boolean isSuc) {
        ServiceContractCertificate queryScc = new ServiceContractCertificate();
        queryScc.setPlatformCode(platformCode);
        queryScc.setIdCode(idCode);
        queryScc.setUserFrom(reqVo.getType());
        List<ServiceContractCertificate> scc = contractCertificateMapper.selectList(new QueryWrapper<>(queryScc)
                .in("account", MD5Utils.MD5Encode(idCardNo), MD5Utils.MD5Encode(companyNo)));
        log.info("idCode:{},证书申请记录信息：{}", idCode, scc);
        if (CollectionUtils.isEmpty(scc)) {
            return false;
        }
        List<ServiceContractCertificate> singleSccList = scc.stream().filter(info -> ContractUserTypeEnum.SINGLE.getType().equals(info.getUserType()))
                .sorted(Comparator.comparing(ServiceContractCertificate::getCreateTime).reversed()).collect(Collectors.toList());
        List<ServiceContractCertificate> companySccList = scc.stream().filter(info -> ContractUserTypeEnum.COMPANY.getType().equals(info.getUserType()))
                .sorted(Comparator.comparing(ServiceContractCertificate::getCreateTime).reversed()).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(singleSccList) || CollectionUtils.isEmpty(companySccList)) {
            return false;
        }
        ServiceContractCertificate singleScc = singleSccList.get(0);
        ServiceContractCertificate companyScc = companySccList.get(0);
        if (isSuc) {
            return CertStatusEnum.SUCCESS.getStatus().equals(singleScc.getStatus()) && CertStatusEnum.SUCCESS.getStatus().equals(companyScc.getStatus());
        }
        return !CertStatusEnum.FAILED.getStatus().equals(singleScc.getStatus()) && !CertStatusEnum.FAILED.getStatus().equals(companyScc.getStatus());
    }

    /**
     * 查询身份签约信息
     * @param platformCode 平台号
     * @param idCode       idcode
     * @return 用户信息
     * */
    private Integer queryIdentityType(String platformCode, Integer idCode) {
        Integer type;
        log.info("获取用户信息,platformCode:{},idCode:{}", platformCode, idCode);
        QueryWrapper<ServiceSign> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id_code", idCode);
        queryWrapper.eq("platform_code", platformCode);
        ServiceSign serviceSign=serviceSignService.getOne(queryWrapper);
        if(Objects.isNull(serviceSign)){
            throw new ServiceException("获取签署用户信息失败,签约信息为空");
        }
        if(!serviceSign.getIsSigned().equals(IsSigndEnum.YES.getCode())){
            throw new ServiceException("获取签署用户信息失败,还没有签约成功");
        }

        if(serviceSign.getCurrentIdentity().equals(SignIdentityEnum.no_identity.getCode()) || serviceSign.getCurrentIdentity().equals(SignIdentityEnum.person.getCode())){
            throw new ServiceException("获取签署用户信息失败,当前身份不对");
        }

        if(serviceSign.getCurrentIdentity().equals(SignIdentityEnum.regist_soho.getCode())){
            type=ContractFromEnum.LE_TAX_INDIVIDUAL.getFrom();
        }else if(serviceSign.getCurrentIdentity().equals(SignIdentityEnum.certified_individual.getCode())){
            type=ContractFromEnum.SELF_CERT_INDIVIDUAL.getFrom();
        }else{
            type=ContractFromEnum.SELF_CERT_COMPANY.getFrom();
        }
        return type;
    }
    /**
     * 查询身份认证时信息
     * @param type
     * @return 用户信息
     * */
    private SignContractPersonBo queryIdentityInfo(Integer type,String platformCode, Integer idCode){
        log.info("获取用户信息,type:{}", type);

        SignContractPersonBo scp = new SignContractPersonBo();
        scp.setIdCode(idCode).setPlatformCode(platformCode).setUserFrom(type);
        //乐税身份
        if(type.equals(SignIdentityEnum.regist_soho.getType())){

            try {
                LeTaxRegisteredAndReturnResult ltr = letaxRegisteredService.leTaxRegisteredAndReturnInfo(idCode, platformCode);
                scp.setSignName(ltr.getName()).setSignIdCardNo(ltr.getIdcardNo())
                        .setSignMobile(ltr.getPhoneNumber())
                        .setSignAddress(StringUtils.isBlank(ltr.getMerchantAddress()) ? "" : ltr.getMerchantAddress())
                        .setCompanyNo(ltr.getMerchantTaxNumber())
                        .setCompantName(StringUtils.isBlank(ltr.getMerchantName()) ? "" : ltr.getMerchantName())
                        .setLeTaxStatus(ltr.getStatus());
            } catch (Exception e) {
                throw new ServiceException("认证信息失效，请到服务费申请重新认证，如有问题请联系客服！");
            }
            log.info("获取用户信息结束,SignContractPersonBo:{}", scp);
            return scp;
        }

        ServiceSelfCertification querySsc = new ServiceSelfCertification();
        querySsc.setPlatformCode(platformCode);
        querySsc.setIdCode(idCode);
        querySsc.setType(type);
        ServiceSelfCertification ssc = serviceSelfCertificationMapper.selectOne(new QueryWrapper<>(querySsc).notIn("status", 3));
        if (Objects.isNull(ssc)) {
            throw new ServiceException("获取签署用户信息失败,自认证信息为空");
        }
        scp.setSignName(ssc.getIdcardName()).setSignIdCardNo(ssc.getIdcardNo())
                .setSignMobile(ssc.getLegalMobile())
                .setSignAddress(StringUtils.isBlank(ssc.getCompanyAddress()) ? "" : ssc.getCompanyAddress())
                .setCompanyNo(ssc.getCompanyNo())
                .setCompantName(StringUtils.isBlank(ssc.getCompanyName()) ? "" : ssc.getCompanyName())
                .setStatus(ssc.getStatus());

        log.info("获取用户信息结束,SignContractPersonBo:{}", scp);
        return scp;
    }

    /**
     * 查询w_service_self_certification表用户信息
     *
     * @param platformCode 平台号
     * @param idCode       idcode
     * @return 用户信息
     */
    private SignContractPersonBo querySscInfo(String platformCode, Integer idCode, SignContractReqVo reqVo) {
        log.info("获取用户信息,platformCode:{},idCode:{}", platformCode, idCode);
        SignContractPersonBo scp = new SignContractPersonBo();
        scp.setIdCode(idCode).setPlatformCode(platformCode).setUserFrom(reqVo.getType());
        switch (reqVo.getType()) {
            case 1:
            case 2:
                ServiceSelfCertification querySsc = new ServiceSelfCertification();
                querySsc.setPlatformCode(platformCode);
                querySsc.setIdCode(idCode);
                querySsc.setType(reqVo.getType());
                ServiceSelfCertification ssc = serviceSelfCertificationMapper.selectOne(new QueryWrapper<>(querySsc).notIn("status", 3));
                if (Objects.isNull(ssc)) {
                    throw new ServiceException("获取签署用户信息失败,自认证信息为空");
                }
                scp.setSignName(ssc.getIdcardName()).setSignIdCardNo(ssc.getIdcardNo())
                        .setSignMobile(ssc.getLegalMobile())
                        .setSignAddress(StringUtils.isBlank(ssc.getCompanyAddress()) ? "" : ssc.getCompanyAddress())
                        .setCompanyNo(ssc.getCompanyNo())
                        .setCompantName(StringUtils.isBlank(ssc.getCompanyName()) ? "" : ssc.getCompanyName())
                        .setStatus(ssc.getStatus());
                break;
            case 3:
                try {
                    LeTaxRegisteredAndReturnResult ltr = letaxRegisteredService.leTaxRegisteredAndReturnInfo(idCode, platformCode);
                    scp.setSignName(ltr.getName()).setSignIdCardNo(ltr.getLegalIdCardNo())
                            .setSignMobile(ltr.getPhoneNumber())
                            .setSignAddress(StringUtils.isBlank(ltr.getMerchantAddress()) ? "" : ltr.getMerchantAddress())
                            .setCompanyNo(ltr.getMerchantTaxNumber())
                            .setCompantName(StringUtils.isBlank(ltr.getMerchantName()) ? "" : ltr.getMerchantName())
                            .setLeTaxStatus(ltr.getStatus());
                } catch (Exception e) {
                    throw new ServiceException("获取签署用户信息失败,乐税用户信息获取失败");
                }
                break;
            default:
                throw new ServiceException("获取签署用户信息失败,请求类型未知");
        }
        log.info("获取用户信息结束,SignContractPersonBo:{}", scp);
        return scp;
    }

    /**
     * 根据模板变量生成合同
     *
     * @param templateNo 模板编号
     * @param tvvList    模板变量
     * @return 合同Id
     */
    private ContractCreateReq createContractByTemplate(String templateNo, List<TemplateVarsVo> tvvList,
                                                       SignContractPersonBo scp, Integer type) {
        ContractCreateReq createReq = new ContractCreateReq();
        createReq.setTid(templateNo);
        createReq.setTemplateValues(getTemplateValues(tvvList, scp, type));
        createReq.setTitle(templateNo);
        //自然月最后一天
        createReq.setExpireTime(getExpireTime());
        //存储5年
        createReq.setHotStoragePeriod(BestSignConstant.HOT_STORAGE_PERIOD);
        return createReq;
    }

    /**
     * 获取过期时间
     *
     * @return 当前月份最后一天截止时间点
     */
    private static String getExpireTime() {
        Date date = DateTimeUtils.getMonthLastDay(new Date());
        return String.valueOf(date.getTime() / 1000);
    }

    /**
     * 获取模板变量
     *
     * @return 模板变量值替换
     */
    private JSONObject getTemplateValues(List<TemplateVarsVo> tvvList, SignContractPersonBo scp, Integer type) {
        JSONObject jsonObject = new JSONObject();
        tvvList.forEach(info -> {
            if (TemplateVarEnum.COMPANY_NAME.getVar().equals(info.getName())) {
                jsonObject.put(info.getName(), scp.getCompantName());
                return;
            }
            if (TemplateVarEnum.COMPANY_NAME1.getVar().equals(info.getName())) {
                jsonObject.put(info.getName(), scp.getCompantName());
                return;
            }
            if (TemplateVarEnum.COMPANY_NO.getVar().equals(info.getName())) {
                jsonObject.put(info.getName(), scp.getCompanyNo());
                return;
            }
            if (TemplateVarEnum.NAME.getVar().equals(info.getName())) {
                jsonObject.put(info.getName(), scp.getSignName());
                return;
            }
            if (TemplateVarEnum.IDENTITY.getVar().equals(info.getName())) {
                jsonObject.put(info.getName(), scp.getSignIdCardNo());
                return;
            }
            if (TemplateVarEnum.ADDRESS.getVar().equals(info.getName())) {
                jsonObject.put(info.getName(), scp.getSignAddress());
                return;
            }
            if (TemplateVarEnum.START_TIME.getVar().equals(info.getName())) {
                jsonObject.put(info.getName(), DateTimeUtils.parseDateAsString(new Date(), DateTimeUtils.DATE_FORMAT));
                return;
            }
            if (TemplateVarEnum.SIGN_NAME.getVar().equals(info.getName())) {
                jsonObject.put(info.getName(), scp.getCompantName());
                return;
            }
            if (TemplateVarEnum.TYPE_NAME.getVar().equals(info.getName())) {
                ContractFromEnum fromEnum = ContractFromEnum.getInstance(type);
                //默认个体工商户
                jsonObject.put(info.getName(), Objects.isNull(fromEnum) ?
                        ContractFromEnum.SELF_CERT_INDIVIDUAL.getShortName() : fromEnum.getShortName());
            }
        });
        return jsonObject;
    }

    /**
     * 生成用户签名/印章图片
     *
     * @param scp 用户身份证号MD5
     * @return 对象信息
     */
    private CreateUserSignatureReq getCreateUserSignatureReq(SignContractPersonBo scp) {
        CreateUserSignatureReq req = new CreateUserSignatureReq();
        req.setAccount(MD5Utils.MD5Encode(scp.getSignIdCardNo()));
        req.setText(null);
        req.setFontName(null);
        //默认30
        req.setFontSize("90");
        req.setFontColor(null);
        return req;
    }

    /**
     * 生成单创企业印章图片
     * * @return 对象信息
     */
    private CreateCompanySignatureReq getCreateDcCompanySignatureReq(String account) {
        CreateCompanySignatureReq req = new CreateCompanySignatureReq();
        req.setAccount(account);
        req.setText(BestSignConstant.DC_COMPANY_NAME);
        req.setFootText(BestSignConstant.DC_COMPANY_NO);
        req.setFootText2(null);
        req.setImageData(BestSignConstant.DC_COMPANY_IMAGE);
        return req;
    }

    /**
     * 生成企业印章图片
     *
     * @param scp 企业信用号MD5
     * @return 对象信息
     */
    private CreateCompanySignatureReq getCreateCompanySignatureReq(SignContractPersonBo scp) {
        CreateCompanySignatureReq req = new CreateCompanySignatureReq();
        req.setAccount(MD5Utils.MD5Encode(scp.getCompanyNo()));
        req.setText(StringUtils.isBlank(scp.getCompantName()) ? "" : scp.getCompantName());
        req.setFootText(scp.getCompanyNo());
        req.setFootText2(null);
        return req;
    }

    /**
     * 获取自动签请求参数
     *
     * @param templateNo 模板编号
     * @param contractId 合同id
     * @param tvvList    变量
     * @return 结果
     */
    private AutoSignContractReq getAutoSignReq(String templateNo, String contractId, String companyNo, List<TemplateVarsVo> tvvList,String account) {
        AutoSignContractReq req = new AutoSignContractReq();
        req.setTid(templateNo);
        req.setContractId(contractId);
        JSONObject vars = new JSONObject();
        tvvList.forEach(info -> {
            if (TemplateVarEnum.SIGNATURE.getVar().equals(info.getName())) {
                JSONObject varName = new JSONObject();
                varName.put("account", account);
                vars.put(info.getName(), varName);
            }
            if (TemplateVarEnum.COMPANY_SIGNATURE.getVar().equals(info.getName())) {
                JSONObject varName = new JSONObject();
                varName.put("account", MD5Utils.MD5Encode(companyNo));
                varName.put("signatureImageWidth", "110");
                varName.put("signatureImageHeight", "110");
                vars.put(info.getName(), varName);
            }
        });
        req.setVars(vars);

        return req;
    }


    /**
     * 获取手动签请求参数
     *
     * @param templateNo 模板编号
     * @param contractId 合同id
     * @param tvvList    变量
     * @return 结果
     */
    private HandSignContractReq getHandSignReq(String transId, String templateNo, String contractId, List<TemplateVarsVo> tvvList,
                                               SignContractPersonBo scp, SignContractReqVo reqVo) {
        HandSignContractReq req = new HandSignContractReq();
        req.setTid(templateNo);
        req.setContractId(contractId);
        String varNamesA = null;
        String varNamesB = null;
        for (TemplateVarsVo info : tvvList) {
            if (TemplateVarEnum.AUTOGRAPH.getVar().equals(info.getName())) {
                varNamesA = info.getName();
                continue;
            }
            if (TemplateVarEnum.START_TIME.getVar().equals(info.getName())) {
                varNamesB = info.getName();
            }
        }

        req.setVarNames(Objects.isNull(varNamesB) ? varNamesA : varNamesA + "," + varNamesB);

        //法人身份证号
        req.setSigner(MD5Utils.MD5Encode(scp.getSignIdCardNo()));
        req.setIsDrawSignatureImage("1");
        req.setSignatureImageName("default");
        req.setVersion("3");
        req.setPushUrl(NotifyConstants.BEST_SIGN_NOTIFY_URL + transId);
        //签署完成页面回跳地址-拼装合同id
        req.setReturnUrl(reqVo.getReturnUrl()+"contractId="+contractId);
        //默认为0 0-无需拖动到页面底部即可确认签署 1-必须拖动到页面底部，表示阅读完毕才能确认签署
        req.setReadAll("1");
        //默认 48 130
        req.setSignatureImageHeight("38");
        req.setSignatureImageWidth("110");

        return req;
    }

    /**
     * @param scp        自认证信息
     * @param contractId 合同Id
     * @return 创建合同关系
     */
    private ServiceContractRelation createContractRelation(String transId, SignContractPersonBo scp, Integer templateId, String contractId, String account) {
        ServiceContractRelation relation = new ServiceContractRelation();
        relation.setBizId(transId);
        relation.setIdCode(scp.getIdCode());
        relation.setPlatformCode(scp.getPlatformCode());
        relation.setUserFrom(scp.getUserFrom());
        relation.setTemplateId(templateId);
        relation.setContractId(contractId);
        relation.setSponsor(account);
        //多方同签
        relation.setAccount(account);
        relation.setCreateTime(DateTimeUtils.now());
        relation.setUpdateTime(DateTimeUtils.now());
        return relation;
    }

    /**
     * 合同关系签署地址
     */
    private ServiceContractRelation updateContractRelation(Integer id, String shortUrl, String expireTime) {
        ServiceContractRelation relation = new ServiceContractRelation();
        relation.setId(id);
        relation.setSignUrl(shortUrl);
        relation.setSignExpireTime(getSecondStringTime(expireTime));
        relation.setUpdateTime(DateTimeUtils.now());
        return relation;
    }

    /**
     * 创建合同
     *
     * @param contractId 合同Id
     * @return 合同DTO
     */
    private ServiceContract createContract(String templateNo, String contractId) {
        ServiceContract contract = new ServiceContract();
        contract.setContractId(contractId);
        contract.setTitle(templateNo);
        contract.setStatus(ContractStatusEnum.PROCESSING.getStatus());
        contract.setCreateTime(DateTimeUtils.now());
        contract.setUpdateTime(DateTimeUtils.now());
        return contract;
    }


    private Date getStringTime(String time) {
        if (StringUtils.isBlank(time)) {
            return null;
        }
        return DateTimeUtils.parseStringAsDate(time, DateTimeUtils.DEFAULT_DATE_TIME_FORMAT);
    }


    private static Date getSecondStringTime(String time) {
        if (StringUtils.isBlank(time)) {
            return null;
        }
        long lt = new Long(time);
        return new Date(lt * 1000);
    }


}
